/*****************************************************************************
 * file  : test.c
 * creat : apleilx
 * data  : 2017/03/02
 *******************************************************************************/
#define __os_obj_creat__ // define objects in rtxapp module
#include "bsp_api.h"
#include "mem_alloc.h"
#include "framework.h"

#if OS_USED > 0

/*****************************************************************************
 * @brief   fun
 *****************************************************************************/
void task_system(const void *argument);
void modbus_task(void const *argument);
void usb_task(void const *argument);
void task_console(void const *argument);

/*****************************************************************************
 * @brief   var
 *****************************************************************************/
osThreadDef(task_console, osPriorityLow7, 1, 0x800);

osMutexDef(eep_mutex);
osMutexDef(q25_mutex);
osMutexDef(printf_mutex);
osMutexDef(malloc_mutex);
osMutexDef(file_mutex);
osMutexDef(lcd_mutex);

/*******************************************************************************
 * @brief: systask , create befor os start
 * @param {*}
 * @return {*}
 ******************************************************************************/
int thread_init(void)
{
	osThreadDef(task_system, osPriorityHigh, 1, 0x400);	
	
	// 系统对象创建
	os_obj.mid_file = osMutexCreate(osMutex(file_mutex));
	os_obj.mid_printf = osMutexCreate(osMutex(printf_mutex));
	os_obj.mid_malloc = osMutexCreate(osMutex(malloc_mutex));
	os_obj.mid_q25 = osMutexCreate(osMutex(q25_mutex));
	os_obj.mid_lcd = osMutexCreate(osMutex(lcd_mutex));
	
	// 系统任务创建
	os_obj.tid_sys_task = osThreadCreate(osThread(task_system), NULL);

	return (0);
}

/*******************************************************************************
 * @brief: created in systask
 * @param {*}
 * @return {*}
 ******************************************************************************/
int thread_create(void)
{
	// 任务创建
	os_obj.tid_console_task = osThreadCreate(osThread(task_console), NULL);
	return (0);
}

/*******************************************************************************
 * @brief: os lock
 * @param {*}
 * @return {*}
 ******************************************************************************/
void os_lock(void)
{
	osKernelLock();
}

void os_unlock(void)
{
	osKernelUnlock();
}

/*******************************************************************************
 * @brief: task info print
 * @param tid name
 * @return {*}
 ******************************************************************************/
void os_task_info_print(osThreadId tid, const char *name)
{
	int stk, stk_used, pused, prio;

	if (!tid)
		return;

	stk = osThreadGetStackSize(tid);
	stk_used = stk - osThreadGetStackSpace(tid);
	pused = stk_used * 100 / stk;
	prio = osThreadGetPriority(tid);

	dbg_print("stack size: %05x, stack used: %5x, <%02d%%>, prio : %2d, name: %s\n",
			  stk,
			  stk_used,
			  pused,
			  prio,
			  name);

	(void)pused;
	(void)prio;
}

/*******************************************************************************
 * @brief: task info
 * @param {*}
 * @return {*}
 ******************************************************************************/
void os_task_info(void)
{
	dbg_puts(SYMBOL_LINE_EQ PTCR);
	
	dbg_print("system stack used : %d %%\n", stack_used() / 10);
	dbg_print("system heap used  : %d %%\n", mem_sram.info->used_max*100 / mem_sram.block_amount);
	dbg_print("ccm    heap used  : %d %%\n", mem_ccm.info->used_max*100 / mem_ccm.block_amount);
	dbg_print("task amount : %d \n", osThreadGetCount());

	os_task_info_print(os_obj.tid_sys_task, "sys task");
	os_task_info_print(os_obj.tid_gui_task, "gui task");
	os_task_info_print(os_obj.tid_ui_oled, "ui oled task");
	os_task_info_print(os_obj.tid_console_task, "console task");
	os_task_info_print(os_obj.tid_flash_task, "flash task");
	os_task_info_print(os_obj.tid_mb_task, "modbus task");
	os_task_info_print(os_obj.tid_str_task, "str task");
	os_task_info_print(os_obj.tid_usb_task, "usb task");
	os_task_info_print(os_obj.tid_hist, "history task");
	os_task_info_print(os_obj.tid_dc_ui, "ui dacai task");
	os_task_info_print(os_obj.tid_par_save, "par save");
}

/*******************************************************************************
 * @brief: task list diaplay
 * @param argc 参数数量
 * @param argv 参数指针
 * @return 错误代码
 ******************************************************************************/
int task_list(int argc, char *argv[])
{
	os_task_info();
	
	return 0;
}
DBG_FUN_EXPORT(task_list);

#else
void os_task_info(void){}
void os_unlock(void){}
void os_lock(void){}
int thread_create(void){return 0;}
int thread_init(void){return 0;}
#endif
